#ifndef NETLIB_THREADPOOL_H
#define NETLIB_THREADPOOL_H

// 线程池

#include "Condition.h"
#include "Mutex.h"
#include "Thread.h"
#include "Types.h"

#include <deque>
#include <vector>

namespace netlib
{

class ThreadPool : noncopyable // 不可拷贝
{
public:
    typedef std::function<void ()> Task;

    explicit ThreadPool(const string& nameArg = string("ThreadPool"));

    ~ThreadPool();

    void setMaxQueueSize(int maxSize) { maxQueueSize_ = maxSize; } // 设置队列容量

    void setThreadInitCallback(const Task& cb) // 设置任务函数
    { threadInitCallback_ = cb; }

    void start(int numThreads); // 启动固定线程数目的线程池

    void stop(); // 关闭线程池

    const string& name() const { return name_; } // 返回线程池名称

    size_t queueSize() const; // 返回队列中元素个数

    void run(Task f); // 向任务队列中添加任务

private:
    bool isFull() const REQUIRES(mutex_);

    void runInThread(); // 线程池中线程入口函数

    Task take(); // 从任务队列中取出任务

    mutable MutexLock mutex_;                               // 易变的互斥锁
    Condition notEmpty_ GUARDED_BY(mutex_);                 // 任务队列非空
    Condition notFull_ GUARDED_BY(mutex_);                  // 任务队列未满
    string name_;                                           // 线程池名称
    Task threadInitCallback_;                               // 线程前调函数
    std::vector<std::unique_ptr<netlib::Thread>> threads_;   // 线程指针数组
    std::deque<Task> queue_ GUARDED_BY(mutex_);             // 任务队列
    size_t maxQueueSize_;                                   // 任务队列容量
    bool running_;                                          // 线程池是否已开启

}; // class ThreadPool end

} // namespace netlib end

#endif